
#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#include <avr/pgmspace.h>

// ATMEL ATMEGA1284P on MEGAJR SMD
//
//                       +---\/---+
//          (D 28) PB0 1 |        | 40 PA0 (D 27) AI 7
//          (D 29) PB1 2 |        | 39 PA1 (D 26) AI 6
//      INT2 (D 8) PB2 3 |        | 38 PA2 (D 19) AI 5
//       PWM (D 9) PB3 4 |        | 37 PA3 (D 18) AI 4
//   PWM/SS (D 10) PB4 5 |        | 36 PA4 (D 17) AI 3
//     MOSI (D 11) PB5 6 |        | 35 PA5 (D 16) AI 2
// PWM/MISO (D 12) PB6 7 |        | 34 PA6 (D 15) AI 1
//  PWM/SCK (D 13) PB7 8 |        | 33 PA7 (D 14) AI 0
//                 RST 9 |        | 32 AREF
//                VCC 10 |        | 31 GND
//                GND 11 |        | 30 AVCC
//              XTAL2 12 |        | 29 PC7 (D 20)
//              XTAL1 13 |        | 28 PC6 (D 21)
//      RX0 (D 0) PD0 14 |        | 27 PC5 (D 22) TDI
//      TX0 (D 1) PD1 15 |        | 26 PC4 (D 23) TDO
// INT0 RX1 (D 2) PD2 16 |        | 25 PC3 (D 24) TMS
// INT1 TX1 (D 3) PD3 17 |        | 24 PC2 (D 25) TCK
//      PWM (D 4) PD4 18 |        | 23 PC1 (D 30) SDA
//      PWM (D 5) PD5 19 |        | 22 PC0 (D 31) SCL
//      PWM (D 6) PD6 20 |        | 21 PD7 (D 7) PWM
//                       +--------+
//

#define NUM_DIGITAL_PINS            32
#define NUM_ANALOG_INPUTS           8
//#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? 31 - (p) : -1)
#define analogInputToDigitalPin(p)  ((p) == 14 || (p) == 15 || (p) == 16 || (p) == 17 || (p) == 18 || (p) == 19 || (p) == 26 || (p) == 27)
#define digitalPinHasPWM(p)         ((p) == 4 || (p) == 5 || (p) == 6 || (p) == 7 || (p) == 9 || (p) == 10 || (p) == 12 || (p) == 13)

#define ifpin(p,what,ifnot)	    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (what) : (ifnot))

static const uint8_t SS   = 10;
static const uint8_t MOSI = 11;
static const uint8_t MISO = 12;
static const uint8_t SCK  = 13;

static const uint8_t SDA = 30;
static const uint8_t SCL = 31;
static const uint8_t LED = 13;

static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 26;
static const uint8_t A7 = 27;

//#define digitalPinToPCICR(p)    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (&PCICR) : ((uint8_t *)0))
//#define digitalPinToPCICRbit(p) (((p) <= 7) ? 1 : (((p) <= 15) ? 3 : (((p) <= 23) ? 2 : 0)))
//#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
//#define digitalPinToPCMSKbit(p) ((p) % 8)

#define digitalPinToPCICR(p)    ifpin(p,&PCICR,(uint8_t *)0)
#define digitalPinToPCICRbit(p) ifpin(p,digital_pin_to_pcint[p] >> 3,(uint8_t *)0)
#define digitalPinToPCMSK(p)    ifpin(p,__pcmsk[digital_pin_to_pcint[]],(uint8_t *)0)
#define digitalPinToPCMSKbit(p) ifpin(p,digital_pin_to_pcint[p] & 0x7,(uint8_t *)0)


#ifdef ARDUINO_MAIN

#define PA 1
#define PB 2
#define PC 3
#define PD 4

const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS] =
{

  24, //D0 PD0
  25, //D1 PD1
  26, //D2 PD2
  27, //D3 PD3
  28, //D4 PD4
  29, //D5 PD5
  30, //D6 PD6
  31, //D7 PD7
  10, //D8 PB2
  11, //D9 PB3
  12, //D10 PB4
  13, //D11 PB5
  14, //D12 PB6
  15, //D13 PB7
  7, //D14 PA7
  6, //D15 PA6
  5, //D16 PA5
  4, //D17 PA4
  3, //D18 PA3
  2, //D19 PA2
  23, //D20 PC7
  22, //D21 PC6
  21, //D22 PC5
  20, //D23 PC4
  19, //D24 PC3
  18, //D25 PC2
  1, //D26 PA1
  0, //D27 PA0
  8, //D28 PB0
  9, //D29 PB1
  17, //D30 PC1
  16, //D31 PC0

};

const uint16_t __pcmsk[] =
{
  (uint16_t)&PCMSK0,
  (uint16_t)&PCMSK1,
  (uint16_t)&PCMSK2,
  (uint16_t)&PCMSK3
};


// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] =
{
	NOT_A_PORT,
	(uint16_t) &DDRA,
	(uint16_t) &DDRB,
	(uint16_t) &DDRC,
	(uint16_t) &DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] =
{
	NOT_A_PORT,
	(uint16_t) &PORTA,
	(uint16_t) &PORTB,
	(uint16_t) &PORTC,
	(uint16_t) &PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] =
{
	NOT_A_PORT,
	(uint16_t) &PINA,
	(uint16_t) &PINB,
	(uint16_t) &PINC,
	(uint16_t) &PIND,
};

const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
	PD, /* 0*/
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PB, /*8*/
	PB,
	PB,
	PB,
	PB,
	PB,
	PA,
	PA,
	PA, /*16*/
	PA,
	PA,
	PA,
	PC,
	PC,
	PC,
	PC,
	PC, /*24*/
	PC,
	PA,
	PA,
	PB,
	PB,
	PC,
	PC /*31*/
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
	_BV(0), /*0*/
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(2), /*8*/
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7), /*13*/
	_BV(0),
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5), /*19*/
	_BV(7),
	_BV(6),
	_BV(5),
	_BV(4),
	_BV(3),
	_BV(2), /*25*/
	_BV(1),
	_BV(0), /*27*/
	_BV(0),
	_BV(1), /*29*/
	_BV(1),
	_BV(0) /*31*/
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
	NOT_ON_TIMER, 	//D0 PD0
	NOT_ON_TIMER, 	//D1 PD1
	NOT_ON_TIMER, 	//D2 PD2
	NOT_ON_TIMER, 	//D3 PD3
	TIMER1B,	 	//D4 PD4
	TIMER1A,	 	//D5 PD5
	TIMER2B,	 	//D6 PD6
	TIMER2A,	 	//D7 PD7
	NOT_ON_TIMER, 	//D8 PB2
	TIMER0A, 		//D9 PB3
	TIMER0B,	 	//D10 PB4
	NOT_ON_TIMER, 	//D11 PB5
	TIMER3A,	 	//D12 PB6
	TIMER3B,	 	//D13 PB7
	NOT_ON_TIMER, 	//D14 PA7
	NOT_ON_TIMER, 	//D15 PA6
	NOT_ON_TIMER, 	//D16 PA5
	NOT_ON_TIMER, 	//D17 PA4
	NOT_ON_TIMER, 	//D18 PA3
	NOT_ON_TIMER, 	//D19 PA2
	NOT_ON_TIMER, 	//D20 PC7
	NOT_ON_TIMER, 	//D21 PC6
	NOT_ON_TIMER, 	//D22 PC5
	NOT_ON_TIMER, 	//D23 PC4
	NOT_ON_TIMER, 	//D24 PC3
	NOT_ON_TIMER, 	//D25 PC2
	NOT_ON_TIMER, 	//D26 PA1
	NOT_ON_TIMER, 	//D27 PA0
	NOT_ON_TIMER, 	//D28 PB0
	NOT_ON_TIMER, 	//D29 PB1
	NOT_ON_TIMER, 	//D30 PC1
	NOT_ON_TIMER 	//D31 PC0
};
#endif // ARDUINO_MAIN
#endif // Pins_Arduino_h
